﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Flame.Controls
{
    public class VerticalPanelScroll : UserControl
    {
        public static VerticalPanelScroll MakeScrollable(IScrollable scrollable)
        {
            IScrollable _scripterControl = scrollable;

            _scripterControl.Control.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
            _scripterControl.Control.Location = new Point(0, 0);

            //this.SuspendLayout();

            var _panelVerticalPanelScroll = new VerticalPanelScroll(scrollable);
            //_panelVerticalPanelScroll.Dock = DockStyle.Fill;
            //Controls.Add(_panelVerticalPanelScroll);

            _scripterControl.OnRefreshed += (s, _e) => { _panelVerticalPanelScroll.CaretPosHasChanged(); };
            _scripterControl.MouseWheelFromChilds += (s, _e) => { _panelVerticalPanelScroll.MoveScroll(_e.Delta); };
            _scripterControl.OnMoveCaretOnScreen += (s, _e) => { _panelVerticalPanelScroll.CaretPosHasChanged(); };
            //_scripterControl.SaveState();

            //this.ResumeLayout();

            return _panelVerticalPanelScroll;
        }
      

        ScrollBar _scrollBar1 = new VScrollBar();

        IScrollable _scripterControlChild;
        int _dy_saved = -1;
        public VerticalPanelScroll(IScrollable child)
        {
            _scrollBar1.Dock = DockStyle.Right;
            Controls.Add(_scrollBar1);

            _scripterControlChild = child;
            Controls.Add(_scripterControlChild.Control);
            base.Load += (_s, _e) =>
            {
                _scrollBar1.Visible = true;
                _scrollBar1.Scroll += (object sender, ScrollEventArgs e) =>
                {
                    SetScroll(-e.NewValue);
                    _scrollBar1.Value = e.NewValue;
                };

                _scripterControlChild.Control.Location = new Point(_scripterControlChild.Control.Location.X, 0);
                Resize += (sender, e) =>
                {
                    _scripterControlChild.Control.Width = Width;

                    int h = _scripterControlChild.Control.Height - Height;
                    _scrollBar1.Visible = h > 0;
                    if (_scrollBar1.Visible)
                        _scrollBar1.Maximum = _scripterControlChild.Control.Height - Height;
                    refreshScrollValue();
                };
            };
        }
        

        void refreshScrollValue()
        {
            _scrollBar1.Visible = _scripterControlChild.Control.Height > Height;
            if (_scrollBar1.Visible)
                _scrollBar1.Maximum = _scripterControlChild.Control.Height - Height;
            int v = -_scripterControlChild.Control.Location.Y;
            if (_scrollBar1.Minimum <= v && v <= _scrollBar1.Maximum)
                _scrollBar1.Value = v;
        }


        bool niceValue(int dy)
        {
            return Height * 0.2f < dy && dy < Height * 0.8f;
        }

        int getdy()
        {
            return _scripterControlChild.CaretOnScreenPosY - PointToScreen(new Point(0, 0)).Y;
        }

        public void CaretPosHasChanged()
        {
            int dy = getdy();
            if (niceValue(dy))
            {
                _dy_saved = dy;
            }
            else
            {
                if (_dy_saved != -1)
                    MoveScroll(_dy_saved - dy);
            }

            //checkIfCaretAcceptable();
        }

        public void SetScroll(int y)
        {
            if (y > 0)
            {
                y = 0;
            }
            else if (_scripterControlChild.Control.Height < Height)
            {
                y = 0;
            }
            else if (_scripterControlChild.Control.Height + y < Height)
            {
                y = Height - _scripterControlChild.Control.Height;
            }

            _scripterControlChild.Control.Location = new Point(_scripterControlChild.Control.Location.X, y);
        }


        public void MoveScroll(int dy)
        {
            SetScroll(_scripterControlChild.Control.Location.Y + dy);
            refreshScrollValue();
        }

        /*private void checkIfCaretAcceptable()
        {
            int y = _scripterControlChild.CaretOnScreenPosY;
        }*/
    }
}
